Skip to content

第二章:Nginx的请求处理流程

Nginx的请求处理流程

image-20250217074327227

注意:

当内存不足时,非阻塞调用退化成阻塞调用。

因为操作系统要缓存inode,当内存不足时,连inode都只能从磁盘读出来时,此时的异步IO都会退化成阻塞调用。这里有篇文章,你可以仔细看下他的实验过程:https://www.nginx.com/blog/thread-pools-boost-performance-9x/

Nginx进程结构

image-20250217074312430

  • 问题

老师好,为什么看NGINX进程的时候能看到cache manager进程,看不到cache loader进程呢?还有在我的环境里ps -ef的时候,甚至cache manager 进程都看不到,这是什么原因呢?

作者回复:

看不到cache manager进程是因为没有配置相关指令,打开nginx的cache功能,第4部分介绍反向代理时会介绍缓存功能的指令。而cache loader进程仅在cache打开时才会有,而且存在时间非常短,它是用于将之前nginx产生的cache信息元数据读入内存中的,读取完成后就会退出。

Nginx进程管理:信号

image-20250222073208579

老师可以讲一下USER1和USER2吗

作者回复:

USR1信号对应于reopen命令,用于重新打开文件,即切割日志用的;== reopen命令

USR2信号用于升级nginx,它会以子进程方式启动另一个nginx。)

执行reload后,master进程会重新生成它的子进程;

对某个worker进程执行TERM信号后,master进程会重新生成一个新的子进程;

image-20250222073423355

测试过程:

bash
kill -HUP kill -SIGHUP 是一样的效果。

image-20250219073229996

image-20250219073250388

案例:nginx总体是多进程

老师好,你说nginx是多进程,一个主进程多个子进程,但是我看网上又说是多线程。请问进程线程怎么区分了呢?master worker模式的都是多进程吗

作者回复: 总体是多进程。每个worker在读取文件这一子功能上,可以使用多线程。之所以会有多线程这一特性,是因为linux内核的限制,详见第132课

案例:ng reload不会中断业务

老师,有个问题问一下!前面的课程说ng reload不会中断业务的使用,但是调用这个方法之后会新启worker,那么这个时候如果旧的worker如果在处理请求也不会受到影响么?还是说只有旧的worker没有要处理的任务之后才会被重启?

作者回复: 新旧worker同时并存,其中旧worker仍然是原进程,它通过epoll_ctl将监听socket从epoll中移出,之前正在处理的TCP连接不受影响,当处理完(对于http请求,就是发完response,其他协议与语义相关)后旧worker正常退出。 因此新建立的TCP连接就会由新worker处理。

案例:SIGCHLD信号

看来很多精彩的评论,有个问题,如果Kill sigterm 杀掉了一个work进程,重新起来的这个work进程是直接fork出来的,因为看评论说master并不能感知到work进程退出,所以这里有点疑问,请老师指教

作者回复: master是worker进程的父进程,在Linux中,子进程退出时,会向父进程发送信号SIGCHLD,所以master进程可以感知到,这才能重新fork拉起新的worker子进程

reload流程

image-20250222075707002

image-20250222075718547

案例:要频繁更改upstream而导致频繁reload

老师你好,如果nginx上的配置的是websocket,且nginx需要频繁的reload。会导致大量的work进程堆积吗?假设一个nginx 上有500个虚拟主机,QPS也十分大,后端都是容器,所以需要频繁更改upstream而导致频繁reload。再加上很多是websocket协议或长连接。nginx性能会有影响吗?

作者回复: 会,如果是频繁修改upstream集群信息,那么不建议使用reload方式,你的修改目标非常简单明确,而reload是重新对所有配置生效,建议使用openresty实现API服务,由API来直接修改upstream信息。

最近也遇到了相同的问题,修改upstream集群执行reload就会导致新的请时进不来,CPU使用率瞬间增高,临时处理的操作是kill老worker进程,看来需要更新下系统架构了。

老师,reload会造成一段时间内worker进程数量大于CPU物理核数的情况,这种情况下在高并发的场景下会带来什么问题?

作者回复: 发生CPU争抢,CPU缓存效率下降,因此在QPS或者并发连接数不变的情况下,nginx总体性能会略有下降

worker进程:优雅的关闭

image-20250225070637122

案例:

nginx优雅关闭主要针对http请求,而非tcp或websocket。因为nginx不会解析tcp的帧,也不会解析websocket的frame,无法识别关闭的时机。

作者回复: 没错!这两种场景下,nginx reload肯定会影响流量,目前无解!

案例:代理 web socket 时,是没办法进行优雅关闭的意思吗(是的)

老师那么代理 web socket 时,是没办法进行优雅关闭的意思吗?

作者回复: 是的

案例:默认worker shutdown timeout这个功能是不打开的

老师,请问下,worker shutdown timeout不设置的情况下,默认的时间是多少来的?

作者回复: 默认这个功能不打开的。

网络传输

image-20250225071730593

TCP流与报文

image-20250225071758171

TCP协议与非阻塞接口

image-20250225071947540

事件分发器是操作系统的吗?

作者回复: 不是,nginx基于epoll自己实现的


案例:

访问:

image-20250225072857976

抓包:

image-20250225072940227

image-20250225073038408

image-20250225073124796

image-20250225073137951

三次捂手:

image-20250225073253698

Nginx的事件驱动模型

image-20250225074156819

image-20250414064422944

epoll

image-20250414064437069

1、基于epoll的事件多路复用减少了进程间切换的次数,使得操作系统少做了相对于用户任务来说的无用功。

2、epoll比select等多路复用方式来说,减少了遍历循环及内存拷贝的工作量,因为活跃连接只占总并发连接的很小一部分。

请求切换

image-20250414071330492

最近更新